package priv.mill.httpclient;

import java.lang.annotation.Annotation;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import priv.mill.httpclient.annotation.HttpGet;
import priv.mill.httpclient.annotation.HttpPost;

@Aspect
@Component
public class HttpClientAdvice {

	private Logger logger = Logger.getLogger(HttpClientAdvice.class);
	
	@Pointcut("@annotation(priv.mill.httpclient.annotation.HttpClient)")
	public void httpClientPoint() {}
	
	@Resource
	private ApplicationContext applicationContext;
	
	@Around("httpClientPoint()")
	public Object around(ProceedingJoinPoint pjp) throws Exception {
		Object[] args = pjp.getArgs();
		try {
			MethodSignature signature = (MethodSignature) pjp.getSignature();
			Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
			Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();
			for (int i = 0; i < parameterAnnotations.length; i++) {
				for (int j = 0; j < parameterAnnotations[i].length; j++) {
					if(isHttoClientAnnotation(parameterAnnotations[i][j])) {
						if(!CharSequence.class.isAssignableFrom(parameterTypes[i])) {
							//TODO 参数类型如果不是String那么就要做JSON注入
							logger.error("the httpclient param must be string type");
							break;
						}
						HttpAnnotationHandler httpAnnotationHandler = getHttpAnnotationHandler(parameterAnnotations[i][j]);//beansOfType.get(parameterAnnotations[i][j].getClass());
						if(httpAnnotationHandler!=null) {
							httpAnnotationHandler.resolve(parameterAnnotations[i][j],args,i);
							
							break;
						}
					}
				}
			}
			Object proceed = pjp.proceed(args);
			return proceed;
		} catch (Throwable e) {
			logger.error(e);
			e.printStackTrace();
			throw new Exception(e.getMessage());
		}
	}

	private HttpAnnotationHandler getHttpAnnotationHandler(Annotation annotation) {
		Map<String, HttpAnnotationHandler> beansOfType = applicationContext.getBeansOfType(HttpAnnotationHandler.class);
		if(annotation instanceof HttpGet) {
			return beansOfType.get("httpGetHttpAnnotationHandler");
		}else if(annotation instanceof HttpPost) {
			return beansOfType.get("httpPostHttpAnnotationHandler");
			
		}
		return null;
	}

	private boolean isHttoClientAnnotation(Annotation annotation) {
		return annotation instanceof HttpGet || annotation instanceof HttpPost;
	}
	
}
